home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample PMSAM / PMSAM Framework / Common / FileUtils.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  19.6 KB  |  931 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        FileUtils.cp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Tim Harnett
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <12>     4/5/95        HDA        fix DoGet's check for folders. Now checks for ioDirMask
  13.         <11>     2/21/95    TMH        metrowerks change, add func prototypes
  14.         <10>     1/11/95    TMH        added Write(StringPtr pascalString)
  15.          <8>    10/20/94    TMH        added Exists()
  16.          <7>    10/14/94    TMH        some file id methods
  17.          <6>    10/13/94    TMH        added Delete()
  18.          <5>     10/6/94    TMH        SetFSSpec does not return an error
  19.          <4>     10/3/94    TMH        added SetType and SetCreator
  20.          <3>     9/30/94    TMH        added CFolderIterator
  21.          <2>     9/27/94    TMH        added CFSSpec, CFolder and CFile descend from CFSSpec
  22.          <1>     9/20/94    TMH        Abandon RoadsideRest embrace Mercury
  23.          <4>     9/20/94    TMH        added overloaded Write(char* str) method
  24.          <3>      9/9/94    TMH        more methods for CFile.  Use of Failures
  25.          <2>     6/14/94    TMH        methods for opening closeing, writing
  26.                  4/18/94    TMH        xxx put comment here xxx
  27.  
  28.     To Do:
  29. */
  30.  
  31. #ifndef __SCRIPT__
  32. #include "Script.h"
  33. #endif
  34.  
  35. #ifndef __ERRORS__
  36. #include "Errors.h"
  37. #endif
  38.  
  39. #ifndef __Debug__
  40. #include "Debug.h"
  41. #endif
  42.  
  43. #ifndef __RESOURCES__
  44. #include "Resources.h"
  45. #endif
  46.  
  47. #ifndef __STRING__
  48. #include "String.h"
  49. #endif
  50.  
  51. #ifndef __STRINGS__
  52. #include "Strings.h"
  53. #endif
  54.  
  55. #ifndef __PLSTRINGFUNCS__
  56. #include "PLStringFuncs.h"
  57. #endif
  58.  
  59.  
  60. #ifndef __THREADS__
  61. #include "Threads.h"
  62. #endif
  63.  
  64. #ifndef __CommonResources__
  65. #include "CommonResources.h"
  66. #endif
  67.  
  68. #ifndef __FileUtils__
  69. #include "FileUtils.h"
  70. #endif
  71.  
  72.  
  73. #ifndef __UFAILURE__
  74. #include "UFailure.h"
  75. #endif
  76.  
  77. Boolean    gFileAsync = true;
  78.  
  79. //--------------------------------------
  80. //        C F S S p e c
  81. //--------------------------------------
  82.  
  83. CFSSpec::CFSSpec(short vRefNum,long parentdDirID,StringPtr name)
  84. {
  85.  
  86.     FSMakeFSSpec(vRefNum,parentdDirID,name,&fFSSpec);
  87. }
  88.  
  89. CFSSpec::CFSSpec(short vRefNum,long parentDirID,char* name)
  90. {
  91.  
  92.     //    See pg 2-35 Inside Macintosh Files 
  93.  
  94.     if( name != 0 )
  95.         c2pstr(name);
  96.         
  97.     if( name == 0 || name[0] == 0 ) {
  98.     
  99.         fFSSpec.vRefNum = vRefNum;
  100.         fFSSpec.parID = parentDirID;
  101.         fFSSpec.name[0] = 0;
  102.         
  103.     } else {
  104.     
  105.         FSMakeFSSpec(vRefNum,parentDirID,(StringPtr)name,&fFSSpec);
  106.     }
  107.     
  108.     if( name != 0 )
  109.         p2cstr((StringPtr)name);
  110. }
  111.  
  112.  
  113. CFSSpec::CFSSpec(HFileInfo* infoPB)
  114. {
  115.     FSMakeFSSpec(infoPB->ioVRefNum,infoPB->ioFlParID,infoPB->ioNamePtr,&fFSSpec);
  116. }
  117.  
  118. void CFSSpec::SetFSSpec(short vRefNum,long parentdDirID,StringPtr name)
  119. {
  120.     FSMakeFSSpec(vRefNum,parentdDirID,name,&fFSSpec);
  121. }
  122.  
  123.  
  124. //-------------------------------------------------------------------------------
  125. OSErr CFSSpec::GetCatInfo(CInfoPBRec& cInfo)
  126. {
  127.  
  128.     //    Caution: that ioNamePtr points into this CFile object.
  129.         
  130.     cInfo.hFileInfo.ioCompletion = NULL;
  131.     cInfo.hFileInfo.ioNamePtr = this->NamePtr();;
  132.     cInfo.hFileInfo.ioVRefNum = this->VRefNum();
  133.     cInfo.hFileInfo.ioFDirIndex = 0;
  134.     cInfo.hFileInfo.ioDirID = this->ParID();
  135.     OSErr err = PBGetCatInfoSync(&cInfo);        // •• async?
  136.     
  137.     return err;
  138.     
  139. }
  140.  
  141.  
  142.  
  143. //-------------------------------------------------------------------------------
  144. OSErr CFSSpec::SetCatInfo(CInfoPBRec& cInfo)
  145. {
  146.  
  147.     //    Caution: that ioNamePtr points into this CFile object.
  148.  
  149.     cInfo.hFileInfo.ioCompletion = NULL;
  150.     cInfo.hFileInfo.ioNamePtr = this->NamePtr();;
  151.     cInfo.hFileInfo.ioVRefNum = this->VRefNum();
  152.     cInfo.hFileInfo.ioDirID = this->ParID();
  153.     OSErr err = PBSetCatInfoSync((CInfoPBRec*) &cInfo);  // •• async?
  154.     
  155.     return err;
  156.     
  157.     
  158. }
  159.  
  160.  
  161. //--------------------------------------
  162. //        C F i l e
  163. //--------------------------------------
  164.  
  165.  
  166. //-------------------------------------------------------------------------------
  167. CFile::CFile()
  168. {
  169.     fRefNum = 0;
  170. }
  171.  
  172. //-------------------------------------------------------------------------------
  173. CFile::CFile(short vRefNum,long parentDirID,StringPtr name) : CFSSpec(vRefNum,parentDirID,name)
  174. {
  175.     fRefNum = 0;
  176. }
  177.  
  178. //-------------------------------------------------------------------------------
  179. CFile::CFile(short vRefNum,long parentDirID,char* name) : CFSSpec(vRefNum,parentDirID,name)
  180. {
  181.     fRefNum = 0;
  182. }
  183.  
  184.  
  185. //-------------------------------------------------------------------------------
  186. CFile::CFile(HFileInfo* infoPB) : CFSSpec(infoPB)
  187. {
  188.     fRefNum = 0;
  189. }
  190.  
  191.  
  192. //-------------------------------------------------------------------------------
  193. OSErr CFile::Create(OSType fileCreator, OSType fileType)
  194. {
  195.     
  196.     return FSpCreate(&fFSSpec,fileCreator,fileType,smSystemScript);
  197. }
  198.  
  199. //-------------------------------------------------------------------------------
  200. OSErr CFile::Open(char permission)
  201. {
  202.     return FSpOpenDF(&fFSSpec,permission,&fRefNum);
  203. }
  204.  
  205. //-------------------------------------------------------------------------------
  206. OSErr    CFile::OpenResourceFork(char permission)
  207. {
  208.         return FSpOpenRF(&fFSSpec,permission,&fRefNum);
  209. }
  210.  
  211. //-------------------------------------------------------------------------------
  212. OSErr CFile::Close()
  213. {
  214.     if( fRefNum != 0 )
  215.         return FSClose(fRefNum);
  216.     
  217.     fRefNum = 0;
  218.     return noErr;
  219. }
  220.  
  221.  
  222.  
  223. //-------------------------------------------------------------------------------
  224. OSErr CFile::Delete()
  225. {
  226.     OSErr osErr =this->Close();
  227.     if( osErr != 0 )
  228.         return osErr;
  229.         
  230.     return FSpDelete(&fFSSpec);
  231. }
  232.  
  233.  
  234. //-------------------------------------------------------------------------------
  235. OSErr CFile::Write(StringPtr thePString)
  236. {
  237.     long dataLen = (long)thePString[0];
  238.     return FSWrite(fRefNum,&dataLen,(Ptr)&thePString[1]);
  239. }
  240.  
  241.  
  242. //-------------------------------------------------------------------------------
  243. OSErr CFile::Write(void* data, long dataLen)
  244. {
  245.     return FSWrite(fRefNum,&dataLen,(Ptr)data);
  246. }
  247.  
  248.  
  249. //-------------------------------------------------------------------------------
  250. OSErr CFile::Write(char* s)        // for writing cstrings
  251. {
  252.     long    dataLen = strlen(s);
  253.     return FSWrite(fRefNum,&dataLen,(Ptr)s);
  254. }
  255.  
  256.  
  257. //-------------------------------------------------------------------------------
  258. long CFile::GetPosition()
  259.     long position = 0;
  260.     FailOSErr( GetFPos(fRefNum, &position) ); 
  261.     
  262.     return position;
  263. }
  264.  
  265.  
  266. //-------------------------------------------------------------------------------
  267. long CFile::GetSize()
  268.     long    dataLength = 0;
  269.      FailOSErr( GetEOF(fRefNum, &dataLength) );
  270.     return dataLength;
  271. }
  272.  
  273.  
  274.  
  275. //-------------------------------------------------------------------------------
  276. void CFile::SetPosition(long newPosition)
  277.     FailOSErr( SetFPos(fRefNum, fsFromStart, newPosition) );
  278. }
  279.  
  280.  
  281.  
  282.  
  283. //-------------------------------------------------------------------------------
  284. OSErr CFile::Read(void* data, long* dataLen)
  285. {
  286.     return FSRead(fRefNum,dataLen,(Ptr)data);
  287. }
  288.  
  289.  
  290.  
  291. //-------------------------------------------------------------------------------
  292. long CFile::ReadUntilChar(void* buf,long* dataLen,char tillChar)
  293. {
  294.     char* p = (char*)buf;
  295.     
  296.     long amountRead = 0;
  297.     while( amountRead < *dataLen ) {
  298.     
  299.     
  300.         char c = this->ReadByte();
  301.         if( c == tillChar)
  302.             break;
  303.         
  304.         amountRead++;
  305.         *p++ = c;
  306.         
  307.     }
  308.     
  309.     return amountRead;
  310.  
  311. }
  312.  
  313.  
  314.  
  315. //-------------------------------------------------------------------------------
  316. char CFile::ReadByte()
  317. {
  318.     char    c = 0;
  319.     long    readLen = 1;
  320.     FailOSErr(  FSRead(fRefNum,&readLen,(Ptr)&c) );
  321.     return    c;
  322. }
  323.  
  324.  
  325.  
  326. //-------------------------------------------------------------------------------
  327. long CFile::ReadLine (char* lineBuf,long maxSize,char lineTerminator) 
  328. {
  329.  
  330.     this->SetToStartOfLine(lineTerminator);
  331.         
  332.     lineBuf[0] = 0;
  333.  
  334.  
  335.     long     fileSize = this->GetSize();
  336.     long     curPosition = this->GetPosition();
  337.     char    c;
  338.     long    charCount = 0;
  339.     
  340.     maxSize--;        // always allow room for the 0 terminator.
  341.     
  342.     while( curPosition < fileSize ) {
  343.     
  344.         c = this->ReadByte();        // avoid failures here!
  345.         curPosition++;
  346.  
  347.         if( charCount > maxSize  ) {
  348.             lineBuf[charCount] = 0;
  349.             Failure(kDataExceedsBufLen,0);    
  350.         }
  351.             
  352.         lineBuf[charCount] = c;
  353.         charCount++;
  354.         
  355.         if( c == lineTerminator )
  356.             break;
  357.             
  358.     }
  359.  
  360.  
  361.     lineBuf[charCount] = 0;
  362.     
  363.     return charCount;
  364. }
  365.  
  366.  
  367.  
  368. //-------------------------------------------------------------------------------
  369. void CFile::SetToStartOfLine(char lineTerminator) 
  370. {
  371.  
  372.         //    Move the file marker to the beginning of the 
  373.         //    next line in the file.
  374.         
  375.         
  376.     FailInfo fi;
  377.     Try(fi) {
  378.     
  379.         long curPosition = this->GetPosition();
  380.         long size = this->GetSize();
  381.         char c;
  382.         
  383.         if( (curPosition < size) && (curPosition != 0) )  {
  384.             this->SetPosition(curPosition-1);
  385.             do {
  386.                 c = this->ReadByte();
  387.             } while( c != lineTerminator );
  388.         }
  389.         
  390.         fi.Success();
  391.     }
  392.  
  393. }
  394.  
  395.  
  396. //-------------------------------------------------------------------------------
  397. OSErr CFile::SetType(OSType fileType)
  398. {
  399.     
  400.     CInfoPBRec    fileInfoPB;
  401.     memset(&fileInfoPB,0,sizeof(CInfoPBRec));
  402.     
  403.     OSErr osErr = this->GetCatInfo(fileInfoPB);
  404.     if( osErr != 0 )
  405.         return osErr;
  406.     
  407.     fileInfoPB.hFileInfo.ioFlFndrInfo.fdType  = fileType;
  408.     
  409.     osErr = this->SetCatInfo(fileInfoPB);
  410.     if( osErr != 0 )
  411.         return osErr;
  412.     
  413.         
  414.     return osErr;
  415.  
  416. }
  417.  
  418.  
  419. //-------------------------------------------------------------------------------
  420. OSErr CFile::SetCreator(OSType fileCreator)
  421. {
  422.     
  423.     CInfoPBRec    fileInfoPB;
  424.     memset(&fileInfoPB,0,sizeof(CInfoPBRec));
  425.     
  426.     OSErr osErr = this->GetCatInfo(fileInfoPB);
  427.     if( osErr != 0 )
  428.         return osErr;
  429.     
  430.     fileInfoPB.hFileInfo.ioFlFndrInfo.fdCreator  = fileCreator;
  431.     
  432.     osErr = this->SetCatInfo(fileInfoPB);
  433.     if( osErr != 0 )
  434.         return osErr;
  435.     
  436.         
  437.     return osErr;
  438.  
  439. }
  440.  
  441.  
  442. //-------------------------------------------------------------------------------
  443. OSErr CFile::SetCreatorAndType(OSType fileCreator,OSType fileType)
  444. {
  445.     
  446.     CInfoPBRec    fileInfoPB;
  447.     memset(&fileInfoPB,0,sizeof(CInfoPBRec));
  448.     
  449.     OSErr osErr = this->GetCatInfo(fileInfoPB);
  450.     if( osErr != 0 )
  451.         return osErr;
  452.     
  453.     fileInfoPB.hFileInfo.ioFlFndrInfo.fdType  = fileType;
  454.     fileInfoPB.hFileInfo.ioFlFndrInfo.fdCreator  = fileCreator;
  455.     
  456.     osErr = this->SetCatInfo(fileInfoPB);
  457.     if( osErr != 0 )
  458.         return osErr;
  459.     
  460.         
  461.     return osErr;
  462.  
  463. }
  464.  
  465.  
  466.  
  467. //-------------------------------------------------------------------------------
  468. long CFile::GetCreationDate()
  469. {
  470.     HParamBlockRec pb;
  471.  
  472.     if (this->GetFileInfo(pb) == noErr)
  473.         return pb.fileParam.ioFlCrDat;
  474.     else
  475.         return 0;
  476.  
  477.  
  478. //-------------------------------------------------------------------------------
  479. long CFile::GetModificationDate()
  480. {
  481.     HParamBlockRec pb;
  482.  
  483.     if (this->GetFileInfo(pb) == noErr)
  484.         return pb.fileParam.ioFlMdDat;
  485.     else
  486.         return 0;
  487.  
  488.  
  489.  
  490.  
  491. //------------------------------------------------------------------------------------------------------------------------
  492. OSErr CFile::GetPhysicalSize(long& dataSize, long& rsrcSize)
  493. {
  494.     HParamBlockRec pb;
  495.     OSErr theErr;
  496.  
  497.     if ((theErr = this->GetFileInfo(pb)) == noErr) {
  498.         dataSize = pb.fileParam.ioFlPyLen;
  499.         rsrcSize = pb.fileParam.ioFlRPyLen;
  500.     }
  501.     return theErr;
  502. }
  503.  
  504.  
  505.  
  506. //------------------------------------------------------------------------------------------------------------------------
  507. OSErr CFile::GetFileInfo(HParamBlockRec& pb)
  508. {
  509.     CStr63 itsName;
  510.  
  511.     itsName = fFSSpec.name;
  512.     pb.fileParam.ioNamePtr = (StringPtr) itsName;
  513.     pb.fileParam.ioVRefNum = this->VRefNum();
  514.     pb.fileParam.ioDirID = this->ParID();
  515.     pb.fileParam.ioFVersNum = 0;
  516.     pb.fileParam.ioFDirIndex = 0;
  517.     OSErr err = PBHGetFInfoSync(&pb);
  518.     pb.fileParam.ioNamePtr = NULL;
  519.     return err;
  520. }
  521.  
  522.  
  523.  
  524. //------------------------------------------------------------------------
  525. OSErr CFile::GetFileID(long* fileID )
  526. {
  527.     *fileID = 0;
  528.  
  529.     FIDParam            fidPB;
  530.     memset(&fidPB,0,sizeof(FIDParam));
  531.     
  532.     fidPB.ioNamePtr        = this->NamePtr();
  533.     fidPB.ioVRefNum      = this->VRefNum();
  534.     fidPB.ioSrcDirID     = this->ParID();
  535.     
  536.     OSErr osErr =  PBCreateFileIDRef( (HParmBlkPtr)&fidPB, false );
  537.  
  538.     if( (osErr == 0) || (osErr == fidExists)) {
  539.         *fileID = fidPB.ioFileID;
  540.         osErr = 0;
  541.     }
  542.     
  543.     
  544.     return osErr;
  545. }
  546.  
  547.  
  548.  
  549.  
  550. //------------------------------------------------------------------------
  551. Boolean CFile::Exists()
  552. {
  553.     HParamBlockRec    pb;
  554.     return this->GetFileInfo(pb) == 0;
  555. }
  556.  
  557. //--------------------------------------
  558. //        C F o l d e r
  559. //--------------------------------------
  560.  
  561.  
  562. CFolder::CFolder(short vRefNum,long parentDirID,StringPtr name) : CFSSpec(vRefNum,parentDirID,name)
  563. {
  564.     fDirID = 0;
  565.     fFolderType = 0;
  566. }
  567.  
  568. CFolder::CFolder(short vRefNum,long parentDirID,char* name) : CFSSpec(vRefNum,parentDirID,name)
  569. {
  570.     fDirID = 0;
  571.     fFolderType = 0;
  572. }
  573.  
  574. OSErr CFolder::CreateFolder()
  575. {
  576.     return FSpDirCreate(&fFSSpec,smSystemScript,&fDirID);
  577. }
  578.  
  579.  
  580. //-------------------------------------------------------------------------
  581. CFolder::CFolder(OSType folderType)
  582. {
  583.     fDirID = 0;
  584.     fFolderType = folderType;
  585.  
  586.     long parentDirID = 0;
  587.     short    vRefNum = 0;
  588.     
  589.     if( folderType == 'root' )
  590.         parentDirID = 2;
  591.         
  592.     if( parentDirID != 2 )        
  593.         FindFolder(0,folderType,kCreateFolder,&vRefNum,&parentDirID);
  594.  
  595.  
  596.     this->SetFSSpec(vRefNum,parentDirID,(StringPtr)0);
  597.  
  598.         // Set the name and directory ID.
  599.         
  600.     DirInfo    dirInfoPB;
  601.     OSErr osErr = this->GetDirInfo(dirInfoPB);
  602.     
  603.     if(osErr == 0 )
  604.         fDirID = dirInfoPB.ioDrDirID;
  605.         
  606. }
  607.  
  608.  
  609.  
  610. //-------------------------------------------------------------------------
  611. OSErr CFolder::GetDirInfo(DirInfo& dirInfoPB)
  612. {
  613.     memset(&dirInfoPB,0,sizeof(DirInfo));
  614.     return this->GetCatInfo((CInfoPBRec&)dirInfoPB);
  615. }
  616.  
  617. //----------------------------------
  618. //    C F o l d e r I t e r a t o r
  619. //-----------------------------------
  620.  
  621.  
  622.  
  623. CFolderIterator::CFolderIterator(CFolder& folder,CFolderIterator::ItemFilter itemFilter)
  624. {
  625.     fItemFilter = itemFilter;
  626.     fIndex = 0;
  627.     fCatInfo = (HFileInfo*)&fCatInfoPB;
  628.     
  629.     fVRefNum = folder.VRefNum();
  630.     fDirID = folder.DirID();
  631.     
  632. }
  633.  
  634. //-------------------------------------------------------------------------------------
  635. HFileInfo*    CFolderIterator::FirstFile()
  636. {
  637.     fIndex = 1;
  638.  
  639.     this->DoGet();
  640.     
  641.     if( fCatInfo->ioResult != 0 )
  642.         return (HFileInfo*)0;
  643.         
  644.     return fCatInfo;
  645. }
  646.  
  647.  
  648. //-------------------------------------------------------------------------------------
  649. HFileInfo*    CFolderIterator::NextFile()
  650. {
  651.     fIndex++;
  652.  
  653.     if( this->More() )
  654.         this->DoGet();
  655.         
  656.     if( fCatInfo->ioResult != 0 )
  657.         return (HFileInfo*)0;
  658.         
  659.     return fCatInfo;
  660. }
  661.  
  662.  
  663.  
  664. //-------------------------------------------------------------------------------------
  665. void    CFolderIterator::DoGet()
  666. {
  667.  
  668.     
  669.     for(;;) {
  670.     
  671.             //    Experience has taught that it is safest
  672.             //    to completely reset the PB every time.
  673.             
  674.         memset(&fCatInfoPB,0,sizeof(CInfoPBRec)); 
  675.         
  676.         fCatInfo->ioFDirIndex = fIndex;
  677.         fCatInfo->ioVRefNum = fVRefNum;
  678.         fCatInfo->ioDirID = fDirID;
  679.         fNameBuf[0] = 0;
  680.         fCatInfo->ioNamePtr = (StringPtr)fNameBuf;
  681.         
  682.         PBGetCatInfo((CInfoPBPtr)fCatInfo,gFileAsync);
  683.         
  684.         do {
  685.             YieldToAnyThread();
  686.         } while( gFileAsync && (fCatInfo->ioResult > 0) );
  687.         
  688.         if( fCatInfo->ioResult != 0 )
  689.             break;
  690.  
  691.  
  692.         if ((fCatInfo->ioFlAttrib & ioDirMask) == ioDirMask) {
  693.             if( fItemFilter == kFoldersOnly || fItemFilter == kFilesAndFolders)
  694.                 break;        // its a folder
  695.         }  else { 
  696.             if( fItemFilter == kFilesOnly || fItemFilter == kFilesAndFolders)
  697.                 break;        // its a file
  698.         }
  699.         
  700.         fIndex++;
  701.         
  702.     }
  703.     
  704.     
  705. }
  706.  
  707.  
  708.  
  709.  
  710.  
  711. //-----------------------
  712. //    Procedural Stuff
  713. //-----------------------
  714.  
  715.  
  716. //------------------------------------------------------------------------------------------------------
  717. #pragma segment Templates
  718. OSErr SearchFolder(short vRefNum, long dirID, Boolean (*DoEachFile)(HFileInfo* filePB,void* refCon), void* refCon )
  719. {
  720.     CInfoPBRec    catPB;
  721.     HFileInfo    *filePB;
  722.     Str255        nameBuf;
  723.     OSErr        err;
  724.     int            index;
  725.  
  726.     index = 1;
  727.     filePB = (HFileInfo*)&catPB;
  728.     do {
  729.         memset(filePB,0,sizeof(CInfoPBRec));
  730.         filePB->ioNamePtr = (StringPtr)&nameBuf;
  731.         filePB->ioFDirIndex = index;
  732.         filePB->ioVRefNum = vRefNum;
  733.         filePB->ioDirID = dirID;
  734.         
  735.         err = PBGetCatInfo((CInfoPBPtr)filePB,0);
  736.         
  737.         if( err == noErr )
  738.             if( DoEachFile((HFileInfo*)&catPB,refCon) ) 
  739.                 break;
  740.  
  741.         index++;
  742.     } while( err == 0 );
  743.     
  744.  
  745.     return err;
  746. }
  747.  
  748.  
  749. //------------------------------------------------------------------------------------------------------
  750. Boolean FindAnyFile(HFileInfo* filePB,void* refCon)
  751. {
  752.     Boolean    haltSearch = false;
  753.     if( (filePB->ioFlAttrib & ioDirMask) == 0 ) {    // skip folders
  754.     
  755.         CFile*    file = (CFile*)refCon;
  756.         FSMakeFSSpec(filePB->ioVRefNum,filePB->ioFlParID,filePB->ioNamePtr,&file->fFSSpec);
  757.         haltSearch = true;
  758.     }
  759.  
  760.     return haltSearch;
  761.     
  762. }
  763.  
  764.  
  765.  
  766. //------------------------------------------------------------------------------------------------------
  767. Boolean __FindFolder(HFileInfo* filePB,void* refCon)
  768. {
  769.     Boolean    haltSearch = false;
  770.     
  771.     if( (filePB->ioFlAttrib & ioDirMask) != 0 ) {        // check only folders
  772.         
  773.         CFolder* folder = (CFolder*) refCon;
  774.         
  775.         if( PLstrcmp(folder->fFSSpec.name,filePB->ioNamePtr) == 0 ) {
  776.             FSMakeFSSpec(filePB->ioVRefNum,filePB->ioFlParID,filePB->ioNamePtr,&folder->fFSSpec);
  777.             folder->fDirID = filePB->ioDirID;
  778.             haltSearch = true;
  779.         }
  780.     }
  781.  
  782.     return haltSearch;
  783.     
  784. }
  785.  
  786.  
  787. //------------------------------------------------------------------------------------------------------
  788. OSErr FindFolder(CFolder* folder)
  789. {
  790.     return SearchFolder(folder->fFSSpec.vRefNum, folder->fFSSpec.parID, __FindFolder,folder);
  791. }
  792.  
  793.  
  794. //------------------------------------------------------------------------------------------------------------------------
  795. Boolean __FindFileByName(HFileInfo* filePB,void* refCon); // the compile insist on a prototype
  796. Boolean __FindFileByName(HFileInfo* filePB,void* refCon)
  797. {
  798.     CFile* file = (CFile*) refCon;
  799.     Boolean haltSearch = false;
  800.     
  801.     if( PLstrcmp(file->fFSSpec.name,filePB->ioNamePtr) == 0 ) {
  802.         FSMakeFSSpec(filePB->ioVRefNum,filePB->ioFlParID,filePB->ioNamePtr,&file->fFSSpec);
  803.         haltSearch = true;
  804.     }
  805.  
  806.     return haltSearch;
  807. }
  808.  
  809.  
  810.  
  811. //------------------------------------------------------------------------------------------------------------------------
  812. Boolean FindFileByName(short vRefNum, long dirID, CFile* fileToFind)
  813. {
  814.     fileToFind->fFSSpec.vRefNum = 0;
  815.     return SearchFolder(vRefNum,dirID,__FindFileByName, fileToFind);
  816. }
  817.  
  818.  
  819. //-------------------------------------------------------------------------------------
  820. int ParseHFSPath(char* pathName,char** folderList)
  821. {
  822.  
  823.     //    Get a list of folder names from a path name
  824.     
  825.     int    folderLevels = 0;
  826.     char* token = strtok(pathName,":");
  827.  
  828.     while( (token!=0) && (folderLevels<kMaxPathLevels) ) {
  829.         folderList[folderLevels++] = token;
  830.         token = strtok(NULL,":");
  831.     }
  832.     
  833.     //    convert them to pascal strings.
  834.     
  835.     for(int i=0;i<folderLevels;i++)
  836.         c2pstr(folderList[i]);
  837.         
  838.     return folderLevels;
  839. }
  840.  
  841.  
  842.  
  843. //-------------------------------------------------------------------------------------
  844. OSErr FocHFSHeirarchy(OSType folderParentType,char* path,CFolder& lastChild)
  845. {
  846.         //    Get the dirID for parent
  847.         
  848.         
  849.     short    rootVRefNum = 0;
  850.     long    parentDirID = 0;
  851.     
  852.     if( folderParentType == 'root' )
  853.         parentDirID = 2;
  854.         
  855.     if( parentDirID != 2 )        
  856.         FindFolder(0,folderParentType,kCreateFolder,&rootVRefNum,&parentDirID);
  857.  
  858.  
  859.         //    Create list of folder names.  
  860.         
  861.         
  862.     char*    folderNames[kMaxPathLevels];
  863.     int    folderLevels = ParseHFSPath(path,folderNames);
  864.     ASSERT(folderLevels!=0);
  865.  
  866.  
  867.  
  868.     for(int i=0;i<folderLevels;i++) {
  869.  
  870.  
  871.         CFolder    aFolder(0,parentDirID,(StringPtr)folderNames[i]);
  872.         OSErr osErr = FindFolder(&aFolder);
  873.  
  874.         if( osErr != 0 )
  875.             aFolder.CreateFolder();
  876.  
  877.  
  878.             //    Cache it. -- it may be the last child
  879.             
  880.             
  881.         lastChild = aFolder;                    // bitwize copy
  882.         parentDirID = lastChild.fDirID;        // the next folder goes is a child of the previous
  883.     }
  884.  
  885.  
  886.     return noErr;    // just an innocent assumption!?!?!
  887.     
  888.  
  889. }
  890.  
  891.  
  892. //-------------------------------------------------------------------------------------
  893. OSErr FocHFSHeirarchyFromResource(short resId,CFolder& lastChild)
  894. {
  895.  
  896.     FolderSpecResource** folderResource = (FolderSpecResource**) ::GetResource('fldr',resId);
  897.     FailResError();
  898.     
  899.     char    path[kMaxPathnameLen];
  900.     BlockMove((*folderResource)->folderPath,path,kMaxPathnameLen); // copy this 'cause it gets modified by strtok below
  901.  
  902.     return FocHFSHeirarchy((*folderResource)->folderParentType,path,lastChild);
  903. }
  904.  
  905.     
  906.  
  907. //-----------------------------------------------------------------------------------
  908. OSErr ExchangeFileIDs(CFile& srcFile,CFile& destFile)
  909. {
  910. #ifdef JUNK
  911.     FIDParam            fidPB;
  912.     memset(&fidPB,0,sizeof(FIDParam));
  913.     
  914.     fidPB.ioNamePtr        = srcFile.NamePtr();
  915.     fidPB.ioVRefNum      = srcFile.VRefNum();
  916.     fidPB.ioSrcDirID     = srcFile.ParID();
  917.     
  918.     fidPB.ioDestNamePtr    = destFile.NamePtr();
  919.     fidPB.ioDestDirID     = destFile.ParID();
  920.  
  921.     return PBExchangeFiles( (HParmBlkPtr)&fidPB, false );
  922. #endif
  923.     return FSpExchangeFiles(&srcFile.fFSSpec,&destFile.fFSSpec);
  924. }
  925.  
  926.